package com.core.handler;

import com.core.exception.BizException;
import com.core.util.LogUtil;
import org.slf4j.Logger;

import java.util.Map;

/**
 * 抽象命令处理器，统一封装执行流程（耗时统计+异常捕获）
 *
 * @author hc
 * @CreateTime 2025/7/29 14:54
 */
public abstract class ExecuteCommandHandler<R> implements CommandHandler {
    protected final Logger logger = LogUtil.getLogger(this.getClass());

    @Override
    public final R execute(Map<String, Object> params) {
        long start = System.currentTimeMillis();
        try {
            // 参数处理链
            Map<String, Object> processedParams = executeChain(params);

            // 执行业务逻辑
            R rawResult = doExecute(processedParams);

            // 后置处理结果（统一封装或增强）
            R finalResult = postProcessResult(rawResult);

            // 耗时日志
            double elapsedSec = (System.currentTimeMillis() - start) / 1000.0;
            logger.info("命令处理器 [{}] 执行耗时: {} s", this.getClass().getSimpleName(), String.format("%.3f", elapsedSec));

            return finalResult;

        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            double elapsedSec = (System.currentTimeMillis() - start) / 1000.0;
            logger.error("命令处理器 [{}] 执行异常，耗时: {} s", this.getClass().getSimpleName(), String.format("%.3f", elapsedSec), e);
            throw new RuntimeException("命令执行失败：" + e.getMessage(), e);
        }
    }

    /**
     * 执行链，顺序调用 before -> handle -> after
     */
    private Map<String, Object> executeChain(Map<String, Object> params) {
        return afterExecute(handleExecute(beforeExecute(params)));
    }

    /**
     * 参数校验、数据预加载
     */
    protected Map<String, Object> beforeExecute(Map<String, Object> params) {
        return params;
    }

    /**
     * 复杂的参数加工、缓存读取、权限校验等
     */
    protected Map<String, Object> handleExecute(Map<String, Object> params) {
        return params;
    }

    /**
     * 后置清理或补充处理（可选重写）
     */
    protected Map<String, Object> afterExecute(Map<String, Object> params) {
        return params;
    }

    /**
     * 业务处理结果后置处理，默认直接返回原结果。
     * 子类或框架可以重写，比如统一封装成 CmdResult
     */
    protected R postProcessResult(R result) {
        return result;
    }

    /**
     * 具体业务逻辑由子类实现
     */
    protected abstract R doExecute(Map<String, Object> params) throws Exception;

}
